/*************************************************************************
> File Name: safe_scanf.c
> Author: icebear
> Mail: 3322366195@qq.com
> Created Time: 2023-07-24 09:07:22
> Description: scanf的危险陷阱 如何安全使用
************************************************************************/

// scanf的格式控制的一般形式为：%[*][宽度][F|N][h|l]类型字符
//  "*"表示该输入项读入后不赋予任何变量，即跳过该输入值
//  "宽度"表示输入读入字符的长度
//  F 、N、h、l分别表示远指针、近指针、短整和长整型
// 类型字符"为 d -- 输入十进制整数 、o -- 输入八进制整数 、
// x -- 输入十六进制整数 、u -- 输入无符号十进制整数
// f或e -- 输入实型数(用小数形式或指数形式) 、c -- 输入单个字符 、
// s -- 输入字符串

// # scanf("%[^/n]%*c",str); 安全的输入字符串
#include <stdio.h>
void safeScanfInt(int *i);
void safeScanfLong(long *l);
void safeScanfDouble(double *d);
void safeScanfFloat(float *f);
// void unsafeScanf();
void safeScanf();
int main(int argc, char const *argv[])
{
    int i;
    long l;
    float f;
    double d;
    while (1)
    {
        // safeScanf();
        // printf("integer :\n");
        // safeScanfInt(&i);
        // printf("int i = %d\n", i);

        // printf("long integer :\n");
        // safeScanfLong(&l);
        // printf("long integer l = %ld\n", l);

        printf("float :\n");
        safeScanfFloat(&f);
        printf("float f = %f\n", f);

        printf("double :\n");
        safeScanfDouble(&d);
        printf("double= %lf\n", d);
    }
}
// void unsafeScanf()
// {
//     printf("unsafeScanf:\n");
//     int i = 5;
//     char arr[4];
//     scanf("%s", arr);
//     printf("%d\n", i);
//     int a = 0, b = 0;
//     scanf("%d%d", &a, &b);
//     printf("a=%d b=%d\n", a, b);
// }
void safeScanf()
{
    printf("safeScanf:\n");
    int a = 0, b = 0;
    scanf("%*[^0-9]"); // 读入所有非数字并丢弃
    scanf("%d", &a);
    scanf("%*[^0-9]"); // 读入所有非数字并丢弃
    scanf("%d", &b);
    // scanf("%*[^0-9]"); // 读入所有非数字并丢弃
    scanf("%*[^\n]%*c");
    // scanf("%*[^\n]");
    // scanf("%*c");
    printf("a=%d b=%d\n", a, b);
}
void safeScanfInt(int *i)
{
    scanf("%*[^0-9]");
    scanf("%d*[^\n]%*c", i);
    // scanf("%*[^0-9]%d*[^\n]%*c", i); 不可用
}
void safeScanfLong(long *l)
{
    scanf("%*[^0-9]");
    scanf("%ld*[^\n]%*c", l);
}
void safeScanfFloat(float *f)
{
    scanf("%*[^0-9]");
    scanf("%f*[^\n]%*c", f);
}
void safeScanfDouble(double *d)
{
    scanf("%*[^0-9]");
    scanf("%lf*[^\n]%*c", d);
}
